package com.etop.jansing.realm;

import com.etop.jansing.dao.ResourcePermissionDao;
import com.etop.jansing.dao.RoleDao;
import com.etop.jansing.dao.UserDao;
import com.etop.jansing.entities.Permission;
import com.etop.jansing.entities.ResourcePermission;
import com.etop.jansing.entities.Role;
import com.etop.jansing.entities.User;
import com.etop.jansing.util.CommonUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;


/**
 * Created by jansing on 2015/10/15.
 */
@Service("myRealm")
public class MyRealm extends AuthorizingRealm {

    @Resource
    private UserDao userDao;
    @Resource
    private RoleDao roleDao;
    @Resource
    private ResourcePermissionDao resourcePermissionDao;

    public MyRealm(){
        this.setCachingEnabled(true);
        this.setAuthenticationCachingEnabled(true);
        this.setAuthenticationCacheName("authenticationCache");
        this.setAuthorizationCachingEnabled(true);
        this.setAuthorizationCacheName("authorizationCache");
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //查出是否有此用户
        User user = userDao.getByUsername(token.getUsername());
        //todo 在这里登陆操作，可以抛出各种异常
        if (user != null) {
            //若存在，将此用户存放到登录认证info中
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        }
        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取登录时输入的用户名
        String loginName = (String) principals.fromRealm(getName()).iterator().next();
        if (StringUtils.isBlank(loginName))
            return null;
        User user = userDao.getByUsername(loginName);
        if (user != null) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //权限信息对象info,用来存放查出的用户的所有的角色（role）及资源权限对（resourcePermission）
            List<Role> roles = roleDao.getByUser(user.getId());
            if(roles!=null) {
                roles.forEach(role -> info.addRole(role.getName()));
            }
            List<ResourcePermission> rps = resourcePermissionDao.getResoPermListByRoles(CommonUtils.getIds(roles));
            if(rps!=null) {

                rps.forEach(rp ->{
                    if(rp.getResoPermString()!=null&&!rp.getResoPermString().isEmpty())
                        info.addStringPermission(rp.getResoPermString());
                });
            }
            return info;
        }
        return null;
    }

    /**
     * 清除某个用户的账号密码缓存
     * @param principals
     */
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    /**
     * 清除某个用户的角色权限缓存
     * @param principals
     */
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除某个用户的所有缓存
     * @param principals
     */
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 清除所有用户的账号密码缓存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 清除所有用户的角色权限缓存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 清除所有用户缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
